/*
 * @(#)WebmethodCollector
 *
 * Copyright 2001-2005 友联创新科技
 *
 */
package com.sinodata.bsm.cicp.collector.webmethod;

import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;

import org.apache.log4j.Logger;
import org.htmlparser.Parser;
import org.htmlparser.filters.NodeClassFilter;
import org.htmlparser.util.NodeList;

import com.sinodata.bsm.cicp.collector.Collector;
import com.sinodata.bsm.cicp.util.HttpUtil;
import com.sinodata.bsm.common.vo.ResPropertyValue;

/**
 * WebmethodCollector.java
 * <p>
 * WebMethod采集器,WebMethod专用的采集器
 *
 * @author 唐力 tangli@uni-mon.com
 * @version 1.0
 * @Date Jun 18, 2009
 */
public class WebmethodCollector extends Collector {
    private static Logger logger = Logger.getLogger(WebmethodCollector.class);
    private static final String REQUEST_URL = "WmRoot/stats-general.dsp";
    private static final String REQUEST_LICENSE_URL = "WmRoot/settings-license.dsp";

    public WebmethodCollector() {

    }

    public List<ResPropertyValue> collect(String ip) {
        String url = this.getParamMap().get("URLAddress");
        String usr = "Administrator";
        String pwd = "manage";
        String[] account = HttpUtil.getURLAccount(url);
        if (account != null) {
            usr = account[0];
            pwd = account[1];
        }
        String[] propMetas = getPropMeta();
        ResPropertyValue propertyValueX = new ResPropertyValue();
        ResPropertyValue.PropValue[] propValues = new ResPropertyValue.PropValue[propMetas.length];
        Map<String, String> nodeMap = this.getNodeMap();
        try {
            this.requestAndFillData(url + (url.endsWith("/") ? REQUEST_URL : "/" + REQUEST_URL), usr, pwd, nodeMap);
            this.requestAndFillData(url + (url.endsWith("/") ? REQUEST_LICENSE_URL : "/" + REQUEST_LICENSE_URL), usr, pwd, nodeMap);
        } catch (Exception e) {
            propValues[8] = ResPropertyValue.createPropValue("NO", propMetas[8]);
            logger.error(e);
        }

        java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("(\\d+)/");
        String v = null;
        String s = nodeMap.get("Req's per minute");
        if (s != null && s.length() > 0) {
            Matcher matcher = pattern.matcher(s);
            if (matcher.find()) {
                v = matcher.group(1);
            }
        }
        propValues[0] = ResPropertyValue.createPropValue(v, propMetas[0]);

        String used = nodeMap.get("Used");
        String total = nodeMap.get("Total");
        v = null;
        pattern = java.util.regex.Pattern.compile("(\\d+)\\s+");
        if (used != null && total != null && used.length() > 0 && total.length() > 0) {
            Matcher matcher = pattern.matcher(used);
            if (matcher.find()) {
                used = matcher.group(1);
            }
            matcher = pattern.matcher(total);
            if (matcher.find()) {
                total = matcher.group(1);
            }
            v = "" + (Integer.parseInt(used) * 100 / Integer.parseInt(total));
        }
        propValues[1] = ResPropertyValue.createPropValue(v, propMetas[1]);

        String t = nodeMap.get("Average Time");
        v = null;
        if (t != null && t.length() > 0) {
            Matcher matcher = pattern.matcher(t);
            if (matcher.find()) {
                v = matcher.group(1);
            }
        }
        propValues[2] = ResPropertyValue.createPropValue(v, propMetas[2]);

        v = nodeMap.get("Total Sessions");
        propValues[3] = ResPropertyValue.createPropValue(v, propMetas[3]);

        v = nodeMap.get("Service Threads");
        propValues[4] = ResPropertyValue.createPropValue(v, propMetas[4]);

        v = null;
        String error = nodeMap.get("Service Errors");
        String req = nodeMap.get("Completed Req's");
        if (error != null && req != null && error.length() > 0 && req.length() > 0) {
            v = "" + (Integer.parseInt(error) * 100 / Integer.parseInt(req));
        }
        propValues[5] = ResPropertyValue.createPropValue(v, propMetas[5]);

        v = nodeMap.get("License Key Expiration");
        propValues[6] = ResPropertyValue.createPropValue(v, propMetas[6]);

        v = null;
        if (req != null && req.length() > 0) {
            v = "" + Integer.parseInt(req);
        }
        propValues[7] = ResPropertyValue.createPropValue(v, propMetas[7]);
        propValues[8] = ResPropertyValue.createPropValue("YES", propMetas[8]);
        propertyValueX.setValues(propValues);
        List<ResPropertyValue> values = new ArrayList<ResPropertyValue>();
        values.add(propertyValueX);
        return values;
    }

    public String[] getParamMeta() {
        return new String[] { "URLAddress" };
    }

    public String[] getPropMeta() {
        return new String[] { "ISHandleRequestsNum", "ISOccupyMemoryRatio", "ISCurrentAvgRequstTime", "ISSessionsNum", "ISServiceThreadsNum", "ISServiceErrRatio", "LicenseExpiryDate", "CurrentFinishedSessionsNum", "LoginSuccessfullyorNot" };
    }

    private void requestAndFillData(String url, String usr, String pwd, Map data) throws Exception {
        URLConnection uc = null;
        uc = new URL(url).openConnection();
        uc.setDoOutput(true);
        String userPassword = usr + ":" + pwd;
        String encoding = new sun.misc.BASE64Encoder().encode(userPassword.getBytes());
        uc.setRequestProperty("Authorization", "Basic " + encoding);
        Parser parser = new Parser(uc);
        NodeClassFilter textFilter = new org.htmlparser.filters.NodeClassFilter(org.htmlparser.tags.TableColumn.class);
        NodeList nl = parser.parse(textFilter);
        String key = "";
        for (int i = 0; i < nl.size(); i++) {
            String str1 = nl.elementAt(i).toPlainTextString();
            if (data.containsKey(str1)) {
                key = str1;
            } else {
                if (data.containsKey(key)) {
                    data.put(key, str1);
                }
                key = "";
            }
        }
    }

    private Map<String, String> getNodeMap() {
        Map<String, String> nodeMap = new HashMap<String, String>();
        nodeMap.put("Memory Usage (average per hour)", "");
        nodeMap.put("Total Sessions", "");
        nodeMap.put("Licensed Sessions", "");
        nodeMap.put("Service Threads", "");
        nodeMap.put("System Threads", "");
        nodeMap.put("Uptime", "");
        nodeMap.put("Completed Req's", "");
        nodeMap.put("Average Time", "");
        nodeMap.put("Service Errors", "");
        nodeMap.put("Req's per minute", "");
        nodeMap.put("Total", "");
        nodeMap.put("Used", "");
        nodeMap.put("Free", "");
        nodeMap.put("License Key Expiration", "");
        return nodeMap;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        WebmethodCollector w = new WebmethodCollector();
        // System.out.println(w.getStats());
        Map p = new HashMap();
        p.put("URLAddress", "http://192.9.200.51:5552");
        w.setParamMap(p);
        w.collect("");

    }

}
